#include "PlayerStateClimb.h"
#include "Ladder.h"
#include "Player.h"

PlayerStateClimb::PlayerStateClimb(Player* player, unsigned short climbState) : PlayerState(player), _climbState(climbState)
{
}


PlayerStateClimb::~PlayerStateClimb(void)
{
}

void PlayerStateClimb::activate()
{
	_player->resetDash();
	_player->removeFlag(GRAVITY_AFFECTED);
	_player->setFlag(GHOST);
	
	_climbStateFptr[CLIMB_STATE_GRAB] = &PlayerStateClimb::grab;
	_climbStateFptr[CLIMB_STATE_CLIMBING] = &PlayerStateClimb::climbing;
	_climbStateFptr[CLIMB_STATE_DONE] = &PlayerStateClimb::done;
	_climbStateFptr[CLIMB_STATE_CLIMB_DOWN] = &PlayerStateClimb::climbDown;

	if (_climbState == CLIMB_STATE_GRAB)
		_player->getAnimationMgr().setAnimation("climb_grab");
	else if (_climbState == CLIMB_STATE_CLIMB_DOWN)
	{
		_player->getAnimationMgr().setAnimation("climb_done");
		_player->getAnimationMgr().setReverse(true);
		_player->_position.y = _player->getLadder()->_position.y + (_player->collisionBox().height * 0.5f) * 0.25f;
	}

	_player->_position.x = _player->getLadder()->_position.x + (_player->getLadder()->getDimension().x * 0.5f);
	_player->_velocity = sf::Vector2f(0.0f, 0.0f);
}

void PlayerStateClimb::deactivate()
{
	_player->removeFlag(GHOST);
	_player->setFlag(GRAVITY_AFFECTED);
	_player->_velocity.y = 0.0f;
}

int PlayerStateClimb::update()
{
	if (_player->damageReceived())
		return PSRV_TAKE_DAMAGE;
	return (this->*_climbStateFptr[_climbState])();
}

int PlayerStateClimb::grab()
{
	if (_player->getAnimationMgr().isDone())
	{
		_player->getAnimationMgr().setAnimation("climb");
		_climbState = CLIMB_STATE_CLIMBING;
	}
	return PSRV_NOTHING;
}

int PlayerStateClimb::climbing()
{
	_player->_velocity.y = 0.0f;

	if (_player->getMovementStateY() == MSY_UP)
	{
		if ((_player->_position.y - (_player->collisionBox().height * 0.5f)) <= _player->getLadder()->_position.y)
		{
			_player->_position.y = _player->getLadder()->_position.y - (_player->collisionBox().height * 0.5f) * 0.25f;
			_climbState = CLIMB_STATE_DONE;
			_player->getAnimationMgr().setAnimation("climb_done");
		}
		else
		{
			_player->getAnimationMgr().setPause(false);
			_player->getAnimationMgr().setReverse(false);
			_player->_velocity.y = -_player->getClimbSpeed() * GameTime::getSingleton()->deltaTime();
		}
	}
	else if (_player->getMovementStateY() == MSY_DOWN)
	{
		if ((_player->flags() & LADDER_COLLISION) != LADDER_COLLISION)
			return PSRV_FALLING;
		_player->getAnimationMgr().setPause(false);
		_player->getAnimationMgr().setReverse(true);
		_player->_velocity.y = _player->getClimbSpeed() * GameTime::getSingleton()->deltaTime();
	}
	else
	{
		_player->getAnimationMgr().setPause(true);
	}

	if (_player->getControlState()->isKeyPressed(CControls::Key(CTRL_JUMP, 0), 0))
		return PSRV_FALLING;
	return PSRV_NOTHING;
}

int PlayerStateClimb::done()
{
	if (_player->getAnimationMgr().isDone())
	{
		_player->_onGround = true;
		_player->_position.y = _player->getLadder()->_position.y - _player->collisionBox().height * 0.5f;
		return PSRV_IDLE;
	}

	return PSRV_NOTHING;
}

int PlayerStateClimb::climbDown()
{
	if (_player->getAnimationMgr().isDone())
	{
		_player->_position.y = _player->getLadder()->_position.y + _player->collisionBox().height * 0.5f;
		_player->getAnimationMgr().setAnimation("climb");
		_climbState = CLIMB_STATE_CLIMBING; 
	}
	return PSRV_NOTHING;
}